package com.example.shop.shops.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.example.shop.base.config.BussinessException;
import com.example.shop.base.constant.RegisterCon;
import com.example.shop.ov.CodeDto;
import com.example.shop.shops.domain.User;
import com.example.shop.shops.service.UserService;
import com.example.shop.shops.service.VerifyCodeService;
import com.example.shop.util.MailUtil;
import com.example.shop.util.StrUtils;
import com.example.shop.util.VerifyCodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class VerifyCodeServiceImpl implements VerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserService userService;

    /**
     * 获取图形验证码
     *
     * @param redisKey
     * @return
     */
    @Override
    public String graph(String redisKey) throws IOException {
        // 1.生成一个验证码
        String randomString = StrUtils.getComplexRandomString(4);
        // 将验证码转成base64
        String base64Graph = VerifyCodeUtils.VerifyCode(100, 50, randomString);
        // 2.存到reids中
        redisTemplate.opsForValue().set(redisKey, randomString, 5, TimeUnit.MINUTES);
        // 3.返回图形验证码
        return base64Graph;
    }

    @Override
    public void getCode(CodeDto codeDto) {
        this.getHome(codeDto);

    }

    @Override
    public void getMelt(CodeDto codeDto) {
        this.getEmail(codeDto);
    }

    // 手机注册走这个
    private void getHome(CodeDto codeDto) {
        if (codeDto.getPhone() != null) {
            // 验证码
            String coderedis = (String) redisTemplate.opsForValue().get(codeDto.getImageCodeKey());
            System.out.println(coderedis); // 注意大小写
            if (StringUtils.isBlank(coderedis) || !codeDto.getImageCodeValue().equalsIgnoreCase(coderedis)) {
                throw new BussinessException("验证码不符");
            }

            // 3.两次发送时间是否大于60秒
            Long ttl = redisTemplate.getExpire(String.format(RegisterCon.REGISTER_PHONE_KEY, codeDto.getPhone()));
            if (null != ttl && ttl > ((RegisterCon.PHONE_CODE_TTL - 1) * 60L)) {
                throw new BussinessException("请60秒后再获取！");
            }
            // 4.手机号是否注册过0
            User user = userService.getOne(new QueryWrapper<User>().eq("phone", codeDto.getPhone()));
            if (null != user) {
                throw new BussinessException("你已经注册过");
            }
            String smsCode = "";
            // 从redis中获取短信验证码的值
            String redisSmsCode = (String) redisTemplate.opsForValue().get(String.format(RegisterCon.REGISTER_PHONE_KEY, codeDto.getPhone()));
            if (StringUtils.isNotBlank(redisSmsCode)) {
                // 如果redis中的值不为空 那么我们发送给客户的就应该是这个
                smsCode = redisSmsCode;
            } else {
                // 如果redis中的值为空 那么我们需要重新生成一个 存到redis中
                smsCode = StrUtils.getComplexRandomString(4);
            }
            log.info("手机号验证码为：{}", smsCode);
            // 6.将手机号验证码存入到redis中
            redisTemplate.opsForValue().set(String.format(RegisterCon.REGISTER_PHONE_KEY, codeDto.getPhone()), smsCode, RegisterCon.PHONE_CODE_TTL, TimeUnit.MINUTES);

        } else {
            throw new BussinessException("手机为空");
        }
    }

    private void getEmail(CodeDto codeDto) {
        if (codeDto.getEmail() != null) {
            // 验证码
            String coderedis = (String) redisTemplate.opsForValue().get(codeDto.getImageCodeKey());
            if (StringUtils.isBlank(coderedis) || !codeDto.getImageCodeValue().equalsIgnoreCase(coderedis)) {
                throw new BussinessException("验证码不符");
            }
            String smsCode = "";
            String redisSmsCode = (String) redisTemplate.opsForValue().get("Email" + codeDto.getEmail());
            if (StringUtils.isNotBlank(redisSmsCode)) {
                // 如果redis中的值不为空 那么我们发送给客户的就应该是这个
                smsCode = redisSmsCode;
            } else {
                // 如果redis中的值为空 那么我们需要重新生成一个 存到redis中
                smsCode = StrUtils.getComplexRandomString(4);
                redisTemplate.opsForValue().set("Email" + codeDto.getEmail(), smsCode, 5, TimeUnit.MINUTES);
                // 3.两次发送时间是否大于60秒
                MailUtil.getMaiUtil("2949163740@qq.com", "2949163740@qq.com", " 五分中内有效", "你的验证码为", smsCode);
            }
            log.info("验证码为：{}", smsCode);
        } else {
            throw new BussinessException("邮箱为空");
        }
    }
}
